﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Lizk.WebScraper;
using System.Runtime.Serialization.Formatters.Binary;

namespace MediaData
{

    public class ScraperFileCache : FileCache
    {
        public string Root { get; set; }

        private Dictionary<string, ScraperResult> inMemoryCache = new Dictionary<string, ScraperResult>();


        public ScraperFileCache(string root)
        {
            this.Root = root;
        }

        public void SaveCompleteCache(string targetFile)
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream fs = File.OpenWrite(targetFile))
            {
                bf.Serialize(fs, inMemoryCache);
            }
        }

        public void LoadCompleteCache(string file)
        {
            if (!File.Exists(file))
                return;
            try
            {
                BinaryFormatter bf = new BinaryFormatter();
                using (FileStream fs = File.OpenRead(file))
                {
                    inMemoryCache = (Dictionary<string, ScraperResult>)bf.Deserialize(fs);
                }
            }
            catch
            {
                inMemoryCache = new Dictionary<string, ScraperResult>();
            }
        }


        public string MakeCachePath(MediaDataSet.TitlesRow title) { return Path.Combine(Root, "tmp_scrapedInfo.xml"); }

        

        public override bool Contains(MediaDataSet.TitlesRow title)
        {
            return inMemoryCache.ContainsKey(title.Type + title.Name);
        }

        public ScraperResult GetResult(MediaDataSet.TitlesRow title)
        {
            if (inMemoryCache.ContainsKey(title.Type+title.Name))
                return inMemoryCache[title.Type + title.Name];

    
            return null;
        }

        public override bool Save(MediaDataSet.TitlesRow title, string artworkPath)
        {
            string cachePath = MakeCachePath(title);

            if (!Directory.Exists(Path.GetDirectoryName(cachePath)))
                Directory.CreateDirectory(Path.GetDirectoryName(cachePath));


                //File.Copy(artworkPath, cachePath);
                ScraperResult result = ScraperResult.FromFile(artworkPath);
                lock (((MediaDataSet)title.Table.DataSet).LockObject)
                {
                    ApplyScraperResult(result, title);
                }

                if (inMemoryCache.ContainsKey(title.Type + title.Name))
                    inMemoryCache.Remove(title.Type + title.Name);
                inMemoryCache.Add(title.Type + title.Name, result);

            return true;
        }

        public bool Save(MediaDataSet.TitlesRow title, ScraperResult result)
        {
            string cachePath = MakeCachePath(title);

            if (!Directory.Exists(Path.GetDirectoryName(cachePath)))
                Directory.CreateDirectory(Path.GetDirectoryName(cachePath));

            try
            {
                //ScraperResult.SaveResult(result, cachePath);
                lock (((MediaDataSet)title.Table.DataSet).LockObject)
                {
                    ApplyScraperResult(result, title);
                }

                if (inMemoryCache.ContainsKey(title.Type + title.Name))
                    inMemoryCache.Remove(title.Type + title.Name);
                inMemoryCache.Add(title.Type + title.Name, result);
            }
            catch
            {
                return false;
            }
            return true;
        }

        public override string FindExisting(string titlePath)
        {
            string volumePath = Path.Combine(titlePath, Path.GetFileName(titlePath) + ".xml");
            if (File.Exists(volumePath))
                return volumePath;
            return null;
        }

        public void ApplyScraperResult(ScraperResult result, MediaDataSet.TitlesRow title)
        {
            title.Description = result.Summary;
            foreach (Episode episode in result.Episodes)
            {
                if (episode.EpisodeNumber == 0)
                    continue;

                if (episode.Season <= 0)
                    episode.Season = 0;

                var episodes = from ep in title.GetEpisodesRows()
                               where ep.Episode == episode.EpisodeNumber && ep.Season == episode.Season
                               select ep;



                bool found = false;
                foreach (var v in episodes)
                {
                    found = true;
                    v.Name = episode.Title;
                    v.Description = episode.Summary == null ? "" : episode.Summary;
                }
                if (!found)
                    ((MediaDataSet)title.Table.DataSet).Episodes.AddEpisodesRow(title, episode.Title, episode.Season, episode.EpisodeNumber, episode.Summary, 0);
            }
        }



        public override void Distribute(MediaDataSet.TitlesRow title, string showPath)
        {
            if (Contains(title))
            {
                try
                {
                    ScraperResult.SaveResult(GetResult(title), Path.Combine(showPath, title.Name + ".xml"));
                }
                catch { }
            }
        }
    }


}
